Skip to content

Add standalone single-module profile smoke test - #548

Open
RonaldHensbergen wants to merge 2 commits into
mainfrom
test/standalone-module-profile
Open

Add standalone single-module profile smoke test#548
RonaldHensbergen wants to merge 2 commits into
mainfrom
test/standalone-module-profile

Conversation

@RonaldHensbergen

@RonaldHensbergen RonaldHensbergen commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Summary

Adds tests/test_standalone_module_profile.py, a generic smoke test that
discovers every module.yaml under modules/ (and modules-experimental/,
if present) and validates it in isolation.

For each module, the test builds a throwaway single-module Profile
referencing only that module — no sibling modules, no dependsOn, no
contract bindings supplied by another module — and runs it through
cli.validator.validate_profile.

Modules with a required consumes entry (e.g. Superset's
metadataDatabase, Dagster's run-storage) can't resolve that binding
standalone, so E030/E041/E042 diagnostics are expected and allowlisted.
Any other diagnostic code (E001, E010, E011, E020, E021, E022,
...) fails the test, since it indicates a genuine problem with the module's
own definition — invalid YAML, a schema violation in module.yaml itself,
or a malformed consumes/provides entry.

Testing

  • python -m unittest tests.test_standalone_module_profile -v
  • python -m unittest discover -s tests -p "test_*.py" -v (full suite, 556 tests, all pass)
  • make lint

@SemTiOne SemTiOne left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, 2 nits.

Comment on lines +30 to +33
# Diagnostic codes that only ever fire because a required contract binding
# (e.g. a database the module consumes) wasn't supplied -- expected when a
# module is exercised standalone rather than wired up in a real profile.
_EXPECTED_UNBOUND_CODES = {"E030", "E041", "E042"}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The allowlist comment calls E030/E041/E042 "unresolved contract binding" codes. E030 is not a contract-binding code. In cli/validator.py, validate_module_configs emits E030 for config-schema violations, and it fires here because the test passes config: {}. validate_contract_bindings emits E041/E042. The allowlist works, but the wrong label invites a future regression: someone who trims it to "contract-binding codes only" breaks the test for every module with required config.

Suggested change
# Diagnostic codes that only ever fire because a required contract binding
# (e.g. a database the module consumes) wasn't supplied -- expected when a
# module is exercised standalone rather than wired up in a real profile.
_EXPECTED_UNBOUND_CODES = {"E030", "E041", "E042"}
# Codes expected when a module runs standalone (no sibling modules, no config
# supplied) instead of wired into a real profile:
# E030 - config-schema violation (fires because we pass config: {}, so any
# module with required config fields reports them missing)
# E041 - a required `consumes` binding could not be resolved (no producer
# module exists in the standalone profile)
# E042 - contract kind mismatch on a consumed binding
_EXPECTED_UNBOUND_CODES = {"E030", "E041", "E042"}

Comment on lines +59 to +78
module_def = yaml.safe_load(module_yaml.read_text(encoding="utf-8"))
version = module_def.get("metadata", {}).get("version", "0.1.0")

profile = {
"apiVersion": "cds/v1alpha1",
"kind": "Profile",
"metadata": {"name": "standalone-smoke", "environment": "local"},
"spec": {
"runtime": {"type": "docker-compose"},
"modules": [
{
"id": "under-test",
"source": source,
"version": version,
"enabled": True,
"config": {},
}
],
},
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version is read from metadata.version and written into the profile instance, but validate_profile never consults it. load_module_instances reads source, enabled, config, dependsOn, id only, and resolve_module_file resolves by source + CDS_MODULE_PATH. The field is dead. Drop it. Also, if metadata.version: is explicit null, .get("version", "0.1.0") returns None and puts "version": None in the profile (harmless only because it is ignored).

Suggested change
module_def = yaml.safe_load(module_yaml.read_text(encoding="utf-8"))
version = module_def.get("metadata", {}).get("version", "0.1.0")
profile = {
"apiVersion": "cds/v1alpha1",
"kind": "Profile",
"metadata": {"name": "standalone-smoke", "environment": "local"},
"spec": {
"runtime": {"type": "docker-compose"},
"modules": [
{
"id": "under-test",
"source": source,
"version": version,
"enabled": True,
"config": {},
}
],
},
}
module_def = yaml.safe_load(module_yaml.read_text(encoding="utf-8"))
profile = {
"apiVersion": "cds/v1alpha1",
"kind": "Profile",
"metadata": {"name": "standalone-smoke", "environment": "local"},
"spec": {
"runtime": {"type": "docker-compose"},
"modules": [
{
"id": "under-test",
"source": source,
"enabled": True,
"config": {},
}
],
},
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants